﻿using Autofac.Extras.DynamicProxy;
using Newtonsoft.Json.Linq;
using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Truron.Purchase.Interface;
using Truron.Purchase.Model;
using Truron.Purchase.Model.RemoteModel;
using Truron.Purchase.Service.DbContext;
using Truron.Purchase.Utility;
using Truron.Purchase.Utility.RedisHelper;

namespace Truron.Purchase.Service
{
    [Intercept(typeof(CustomAutofacAop))]
    public class Purchase_OuterNoteService:IPurchase_OuterNoteService
    {
        private List<Purchase_OuterNote> Init(bool isInit = false)
        {
            try
            {
                if (isInit)//初始化
                    RedisBase.Hash_Remove(StaticConstraint.PurchaseOuterNoteCacheKey);
                var noteList = RedisBase.Hash_GetAll<Purchase_OuterNote>(StaticConstraint.PurchaseOuterNoteCacheKey);
                if (noteList != null && noteList.Count > 0)
                    return noteList;

                noteList = DapperDbContext.Query<Purchase_OuterNote>("select * from [Purchase_OuterNote] where Status != @Status", new { Status = Status.delete }).ToList();
                if (noteList.Count > 0)
                {
                    foreach (var item in noteList)
                        RedisBase.Hash_Set(StaticConstraint.PurchaseOuterNoteCacheKey, item.Id, item);
                    RedisBase.Item_SetExpire(StaticConstraint.PurchaseOuterNoteCacheKey, DateTime.Now.AddDays(7));
                }
                return noteList;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"初始化单据数据失败,isInit:{isInit},详细:{ex.ToString()}");
            }
            return new List<Purchase_OuterNote>();
        }
        public (int count, List<Purchase_OuterNote> list) GetNoteList(string searchKey, int pageSize, int pageIndex,string searchJson, int outerStatus, List<int> ownerIds)
        {
            var queryParam = searchJson.ToJObject();
            int pageNum = (pageIndex - 1) * pageSize;
            var noteList = Init().Where(x => (string.IsNullOrEmpty(searchKey) || x.Code.Contains(searchKey))).ToList();
            
            if(outerStatus==1)
            {
                noteList=noteList.FindAll(x => x.FlowStatus == 0 || x.FlowStatus == 1 || x.FlowStatus == 2);
            }
            else if(outerStatus==2)
            {
                noteList = noteList.FindAll(x => x.FlowStatus == 3);
            }
            else if (outerStatus == 3)
            {
                noteList = noteList.FindAll(x => x.FlowStatus == 4);
            }
            if (!queryParam["beginTime"].IsEmpty())
            {
                noteList = noteList.FindAll(x => x.CreateTime >= Convert.ToDateTime(queryParam["beginTime"]));
            }
            if (!queryParam["endTime"].IsEmpty())
            {
                noteList = noteList.FindAll(x => x.CreateTime <= Convert.ToDateTime(queryParam["endTime"]));
            }
            if (!queryParam["Code"].IsEmpty())
            {
                noteList = noteList.FindAll(x => x.Code.Contains(queryParam["Code"].ToString()));
            }
            if (!queryParam["BussinessType"].IsEmpty())
            {
                noteList = noteList.FindAll(x => x.BussinessType.Contains(queryParam["BussinessType"].ToString()));
            }
            if (!queryParam["Scope"].IsEmpty())
            {
                noteList = noteList.FindAll(x => x.Scope.Contains(queryParam["Scope"].ToString()));
            }
            if (!queryParam["type"].IsEmpty())
            {
                if (queryParam["type"].ToString() == "user")
                {
                    noteList = noteList.FindAll(x => x.OwnerId == (int)queryParam["value"]);
                }
                else if (queryParam["type"].ToString() == "status")
                {
                    if((int)queryParam["value"]==0)
                    {
                        noteList = noteList.FindAll(x => x.FlowStatus == 0 || x.FlowStatus == 1 || x.FlowStatus == 2 );
                    }
                    else
                    {
                        noteList = noteList.FindAll(x => x.FlowStatus == (int)queryParam["value"]);
                    }
                }
                else if (queryParam["type"].ToString() == "statususer")
                {
                    string[] arr = queryParam["value"].ToString().Split("-");
                    if(Convert.ToInt32(arr[0])==0)
                    {
                        noteList = noteList.FindAll(x => (x.FlowStatus == 0|| x.FlowStatus == 1 || x.FlowStatus == 2 ) && x.OwnerId == Convert.ToInt32(arr[1]));
                    }
                    else
                    {
                        noteList = noteList.FindAll(x => x.FlowStatus == Convert.ToInt32(arr[0]) && x.OwnerId == Convert.ToInt32(arr[1]));
                    }
                   
                }
                else if (queryParam["type"].ToString() == "userstatus")
                {
                    
                    string[] arr = queryParam["value"].ToString().Split("-");
                    if (Convert.ToInt32(arr[1]) == 0)
                    {
                        noteList = noteList.FindAll(x => (x.FlowStatus == 0 || x.FlowStatus == 1 || x.FlowStatus == 2) && x.OwnerId == Convert.ToInt32(arr[0]));
                    }
                    else
                    {
                        noteList = noteList.FindAll(x => x.FlowStatus == Convert.ToInt32(arr[1]) && x.OwnerId == Convert.ToInt32(arr[0]));
                    }
                    
                }
            }
            else
            {
                if (ownerIds.Count > 0)
                {
                    noteList = noteList.FindAll(x => ownerIds.Contains(x.OwnerId));
                }
            }
            var pagelist = noteList.OrderBy(x => x.CreateTime).Skip(pageNum).Take(pageSize).ToList();
            return (noteList.Count, pagelist);
        }
        public Purchase_OuterNote GetPurchase_OuterNoteDetail(int NoteId)
        {
            return Init().Where(x => x.Id == NoteId).FirstOrDefault();
        }
        public (int NoteId, decimal SinglePrice) SaveNote(int userId, Purchase_OuterNote ent)
        {
            IDbModelService<Purchase_OuterNote> db = new DbModelService<Purchase_OuterNote>();
            if (ent.Id==0)
            {
                using (var conn = DapperHelper.Instance.OpenCurrentDbConnection())
                {
                    var transaction = conn.BeginTransaction();
                    try
                    {
                        ent.FlowStatus = 0;
                        ent.Code = $"C{DateTime.Now.ToString("yyMMddfff")}{new Random(Guid.NewGuid().GetHashCode()).Next(10001, 99999)}";
                        ent.RealMoney = 0;
                        var noteid= db.InsertOne(ent,conn,transaction);
                        ent.Id = noteid;
                        RedisBase.Hash_Set(StaticConstraint.PurchaseOuterNoteCacheKey, noteid, ent);
                        transaction.Commit();
                        return (noteid,Math.Round(ent.Price/ent.TypeNum, 2));
                    }
                    catch(Exception ex)
                    {
                        transaction.Rollback();
                        return (-1,0);
                    }
                }
            }
            else
            {
                using (var conn = DapperHelper.Instance.OpenCurrentDbConnection())
                {
                    var transaction = conn.BeginTransaction();
                    try
                    {
                       db.UpdateById(ent, conn, transaction);
                        transaction.Commit();
                        if (ent != null)//更新线索缓存
                        {
                            
                            RedisBase.Hash_Remove(StaticConstraint.PurchaseOuterNoteCacheKey, ent.Id.ToString());
                            RedisBase.Hash_Set(StaticConstraint.PurchaseOuterNoteCacheKey, ent.Id, ent);
                        }
                        return (ent.Id, Math.Round(ent.Price / ent.TypeNum, 2));
                    }
                    catch
                    {
                        transaction.Rollback();
                        return (-1, 0);
                    }
                }
            }
        }
        public Purchase_OuterNoteApproval ApproveNote(Purchase_OuterNoteApproval entity, UserCache userinfo,int SendUser,string SendUserName,int step)
        {
            Purchase_OuterNote OuterNote = Init().Find(x => x.Id == entity.NoteId);
            int stempNo = step;
            if (entity.Action==1)
            {
                if(stempNo == 1)
                {
                    if(OuterNote.Price>100000)
                    {
                        stempNo = 2;
                    }
                    else
                    {
                        stempNo = 3;
                    }
                }
                else
                {
                    stempNo++;
                }
                if (FlowTemplate.OuterNoteFlow.Exists(x => x.Step== stempNo))
                {


                    Purchase_OuterNoteApproval approve = new Purchase_OuterNoteApproval();
                    approve.IsFinish = 0;
                    approve.StepNo = stempNo;
                    approve.NoteId = entity.NoteId;
                    approve.Approver = FlowTemplate.OuterNoteFlow.Find(x => x.Step == stempNo).AuditorId;
                    approve.ApproverName = FlowTemplate.OuterNoteFlow.Find(x => x.Step == stempNo).NodeName;
                    approve.Comment = "";
                    return approve;
                }
                else
                {
                    OuterNote.FlowStatus = (int)OuterNoteStatus.finish;
                    SaveNote(userinfo.UserId, OuterNote);
                    return null;
                }
            }
            else
            {
                Purchase_OuterNoteApproval approve = new Purchase_OuterNoteApproval();
                //approve.Create(userToken);
                approve.IsFinish = 0;
                approve.StepNo = 0;
                approve.NoteId = entity.NoteId;
                approve.Approver = SendUser;
                approve.ApproverName = SendUserName;
                return approve;
            }
            
        }
        public List<Purchase_OuterNote> GetRelationList(List<int> NoteIds)
        {
            return Init().Where(x => NoteIds.Contains(x.Id)).ToList();
        }
        public List<Purchase_OuterNote> GetPreRelationNoteList()
        {
            return Init().Where(x => x.FlowStatus != (int)OuterNoteStatus.close).ToList();
        }
        public decimal FinishOuterNote(int NoteId, decimal RealMoney, UserCache userCache)
        {
            IDbModelService<Purchase_OuterNote> db = new DbModelService<Purchase_OuterNote>();
            using (var conn = DapperHelper.Instance.OpenCurrentDbConnection())
            {
                Purchase_OuterNote entity = Init().Find(x => x.Id == NoteId);
                entity.LastUpdateTime = DateTime.Now;
                entity.LastUpdateUser = userCache.UserId;
                entity.FlowStatus = (int)OuterNoteStatus.close;
                entity.RealMoney = RealMoney;
                db.UpdateById(entity, conn);
                RedisBase.Hash_Remove(StaticConstraint.PurchaseOuterNoteCacheKey, entity.Id.ToString());
                RedisBase.Hash_Set(StaticConstraint.PurchaseOuterNoteCacheKey, entity.Id, entity);
                return entity.RealMoney / entity.TypeNum;
            }
                
        }
        public List<Purchase_OuterNote> GetAllList()
        {
            return Init().ToList();
        }

    }
}
